﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Students
{
    public class Program
    {
        private const int StudentsAmount = 15;
        private static Random random = new Random();

        public static void Main()
        {
            List<Group> groups = new List<Group>();
            groups.Add(new Group(0, "Basement geeks"));
            groups.Add(new Group(1, "Informatics"));
            groups.Add(new Group(2, "Mathematics"));
            groups.Add(new Group(3, "Science"));
            groups.Add(new Group(4, "Physics"));

            string[] domains = { "abv.bg", "gmail.com", "yahoo.com", "hotmail.bg", "facebook.com" };
            List<Student> students = new List<Student>();
            for (int i = 0; i < StudentsAmount; i++)
            {
                List<int> marks = new List<int>();
                for (int j = 0; j < random.Next(1, 20); j++)
                {
                    marks.Add(random.Next(2, 7));
                }
                students.Add(new Student("Pesho" + i, "Peshov" + i,
                    int.Parse(610 + string.Format("{0:000}", i)),
                    "(0" + i % 10 + ") 555-555-555",
                    "pesho@" + domains[random.Next(domains.Length)], 
                    marks, random.Next(groups.Count)));
            }

            //1. Students with GroupNumber = 2, ordered by FirstName.
            //var group2 =
            //    from student in students
            //    where student.GroupNumber == 2
            //    orderby student.FirstName
            //    select student;
            //group2.ToList().ForEach(x => Console.WriteLine(x + "\n"));

            //2. Students with GroupNumber = 2, ordered by FirstName.
            //students.Where(x => x.GroupNumber == 2).OrderBy(x => x.FirstName).
            //    ToList().ForEach(x => Console.WriteLine(x + "\n"));

            //3. Students with emails in abv.bg
            //var abvbg =
            //    from student in students
            //    where student.Email.EndsWith("@abv.bg")
            //    select student;
            //abvbg.ToList().ForEach(x => Console.WriteLine(x + "\n"));

            //4. Students with phones from Sofia.
            //var sofiaPhones =
            //    from student in students
            //    where Regex.IsMatch(student.Tel, @"^(\+359 ?)?\(02\)")
            //    select student;
            //sofiaPhones.ToList().ForEach(x => Console.WriteLine(x + "\n"));

            //5. Students with at least 1 mark = 6;
            //var excellents =
            //    from student in students
            //    where student.Marks.Contains(6)
            //    select new 
            //    { 
            //        FullName = student.FirstName + " " + student.LastName, 
            //        Marks = student.Marks 
            //    };
            //foreach (var student in excellents)
            //{
            //    Console.Write("{0}: ", student.FullName);
            //    foreach (var mark in student.Marks)
            //    {
            //        Console.Write("{0} ", mark);
            //    }
            //    Console.WriteLine();
            //}

            //6. Students with at least 2 marks = 2;
            //students.Where(student => student.Marks.Count(mark => mark == 2) == 2).
            //    ToList().ForEach(x => Console.WriteLine(x + "\n"));

            //7. Marks from students with 5th and 6th number in their FN = 06
            //students.Where(student => student.FN.ToString().Substring(4, 2) == "06").
            //    Select(student => student.Marks).ToList().
            //    ForEach(marks => 
            //    { 
            //        Console.Write("Marks:"); 
            //        marks.ForEach(mark => Console.Write(" {0}", mark)); 
            //        Console.WriteLine(); 
            //    });

            //8. Students from the Mathematics department.
            //string department = "Mathematics";
            //Console.WriteLine("{0}:", department);
            //students.Join(groups, s => s.GroupNumber, g => g.GroupNumber, (s, g) => 
            //    new { FullName = s.FirstName + " " + s.LastName, g.DepartmentName }).
            //    Where(x => x.DepartmentName == department).ToList().
            //    ForEach(x => Console.WriteLine("{0}", x.FullName));

            //9. The string with the maximum length.
            //string[] array = { "", "22", "32167", "5", "215", "007" };
            //Console.WriteLine(array.First(s => s.Length == array.Max(x => x.Length)));
            //var maxLength = 
            //    from str in array
            //    where str.Length == array.Max(x => x.Length)
            //    select str;
            //Console.WriteLine(maxLength.First());

            //10. Group students by GroupName.
            //var groupedStudents = 
            //    from r in 
            //        from s in students
            //        join g in groups on s.GroupNumber equals g.GroupNumber
            //        select new { FullName = s.FirstName + " " + s.LastName, g.DepartmentName }
            //    orderby r.DepartmentName
            //    group r by r.DepartmentName;
            //foreach (var group in groupedStudents)
            //{
            //    Console.WriteLine("{0}:", group.Key);
            //    foreach (var student in group)
            //    {
            //        Console.WriteLine("\t{0}", student.FullName);
            //    }
            //} 

            //11. Group students by GroupName.
            //students.OrderBy(x => x.FirstName).ThenBy(x => x.LastName).
            //    Join(groups, s => s.GroupNumber, g => g.GroupNumber, (s, g) =>
            //        new { FullName = s.FirstName + " " + s.LastName, g.DepartmentName }).
            //    GroupBy(x => x.DepartmentName).OrderBy(x => x.Key).ToList().
            //    ForEach(x =>
            //    {
            //        Console.WriteLine("{0}:", x.Key);
            //        x.ToList().ForEach(s => Console.WriteLine("\t{0}", s.FullName));
            //    });
        }
    }
}
